package com.googlecode.cnasort.cc.rmi.client.core;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.rmi.RemoteException;
import org.apache.log4j.Logger;
import com.googlecode.cnasort.cc.rmi.common.RMIFileLoaderConnectorV0;
import com.googlecode.cnasort.cc.rmi.common.data.RMIDirectory;
import com.googlecode.cnasort.cc.rmi.common.data.RMIFile;
import com.googlecode.cnasort.cc.rmi.common.data.impl.RMIDirectoryImpl;

public class FileLoaderClientCoreV0Impl implements FileLoaderClientCore
{
    private static final Logger logger = Logger.getLogger( FileLoaderClientCoreV0Impl.class );

    private RMIFileLoaderConnectorV0 fileLoaderConnector;
    private PrintStream out;
    private File outputDirFile;
    private FileLoaderClientCoreFilters filters;

	private String prefixToDownload;

    public FileLoaderClientCoreV0Impl(
        RMIFileLoaderConnectorV0    fileLoaderConnector,
        PrintStream                 out,
        File                        outputDirFile,
        FileLoaderClientCoreFilters filers
        ) throws RemoteException
    {
        if( fileLoaderConnector.connect() ) {
            this.fileLoaderConnector    = fileLoaderConnector;
            this.out                    = out;
            this.outputDirFile          = outputDirFile;
            this.filters                = filers;
            }
        else {
            logger.warn( "Connection not allowed" );

            throw new SecurityException();
            }
    }

    public File getOutputDirFile()
    {
        return outputDirFile;
    }

    @Override
	public void doQuit() throws RemoteException
    {
        fileLoaderConnector.quit();
    }

    @Override
	public void doDownload( final String prefixToDownload ) throws IOException
    {
    	this.prefixToDownload = prefixToDownload;
        doDownload( new RMIDirectoryImpl( new File( prefixToDownload ) ) );
    }

    private void doDownload(RMIDirectory...folders) throws IOException 
    {
        for( RMIDirectory folder : folders ) {
            RMIDirectory[] subFolders = fileLoaderConnector.getDirectories( folder );

            doDownload( subFolders );

            RMIFile[] files = fileLoaderConnector.getFiles( folder );

            for( RMIFile file : files ) {
                //if( ! file.getName().equals( "00001.MTS" ) ) {
                doDownload( file );
                }
            }
	}

	private void doDownload(RMIFile file) throws IOException 
	{
		byte[] bytes = fileLoaderConnector.getFileContent( file );
		
        System.out.println( "getting: " + file.getFile() );

        String name       = file.getFile().getPath().substring( prefixToDownload.length() );
        File   outputFile = new File( getOutputDirFile(), name );
        File   parentFile = outputFile.getParentFile();

        if( ! parentFile.exists() ) {
            parentFile.mkdirs();
            }

        System.out.println( "writing: " + outputFile + " * " + parentFile );

        OutputStream os = new BufferedOutputStream( new FileOutputStream ( outputFile ) );

        try {
            os.write( bytes );
            }
        finally {
            os.close();
            }
	}

	@Override
	public void printDirectoriesAndFiles() throws RemoteException
    {
        printDirectoriesAndFiles( this.fileLoaderConnector.getRootDirectories() );
    }

    private void printDirectoriesAndFiles( final RMIDirectory[] folders ) throws RemoteException
    {
        for( RMIDirectory folder : folders ) {
            if( this.filters.getDirectoryFilter().accept( folder ) ) {
                out.println( "D:" + folder );

                RMIDirectory[] subFolders  = getDirectories( folder );

                printDirectoriesAndFiles( subFolders );

                RMIFile[] files = getFiles( folder );

                for( RMIFile file : files ) {
                    if( this.filters.getFileFilter().accept( file ) ) {
                        out.println( "F:" + file );
                        }
                    }
                }
            }
    }

    public RMIDirectory[] getDirectories( RMIDirectory folder ) throws RemoteException
    {
        return fileLoaderConnector.getDirectories( folder );
    }

    public RMIFile[] getFiles( RMIDirectory folder ) throws RemoteException
    {
        return fileLoaderConnector.getFiles( folder );
    }

}
